/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Audio.java
 *
 * Created on 01-10-2009, 04:44:44 PM
 */

package secureplace;



import java.io.*;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioFormat;

/**
 *
 * @author hanscker
 */
public class Audio extends javax.swing.JDialog {

    
    static ByteArrayOutputStream byteArrayOutputStream;
    private static TargetDataLine targetDataLine;
    private static boolean ultimoFrameGuardado = false;
    static boolean stopCapture;
    static boolean ventanaConfiguracionAbierta = false;


    public Audio() {
        
    }

    /** Creates new form Audio */
    public Audio(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        initComponents();
        //inicio();
    }

    static void inicio() {
        //Create a thread to capture the
        // microphone data and start it
        // running.
        //System.out.println("inicio()");
        Thread captureThread = new Thread(new CaptureThread());
        captureThread.start();
    }

    private static class CaptureThread extends Thread {
    //Get everything set up for
        // capture
    AudioFormat audioFormat = getAudioFormat();
    DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class,audioFormat);
    //An arbitrary-size temporary holding
    // buffer
    byte tempBuffer[] = new byte[10000];
    void definiciones(){
        //System.out.println("definiciones()");
        try{
        targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);
        targetDataLine.open(audioFormat);
        targetDataLine.start();
        } catch (Exception e) {
        System.out.println(e);
        }
    }
    @Override
    public void run(){
        //System.out.println("run()");
        definiciones();
        byteArrayOutputStream = new ByteArrayOutputStream();
        stopCapture = false;
        ultimoFrameGuardado = false;

        try{
            //Loop until stopCapture is set
            // by another thread that
            // services the Stop button.
            while(!stopCapture){
                int count = 0;
                float level = 0;

                //Read data from the internal
                // buffer of the data line.
                int cnt = targetDataLine.read(tempBuffer,0,tempBuffer.length);
                byte[] frameSample = new byte[tempBuffer.length];
			for (int jj=0; jj<frameSample.length; jj++) {
					frameSample[jj] = tempBuffer[jj];
                }
                double[] signalSize = frameToSignedDoubles( frameSample );
                for (int jj=0; jj<signalSize.length; jj++) {
					level += Math.abs(signalSize[jj]);
					count++;
                }
                double averageLevel = level/count;
                int nivel = (int) (averageLevel*100);
                if (!secureplace.SecurePlaceApp.modo.equalsIgnoreCase("Seguro")) {
                    //System.out.println("Nivel:"+nivel+" Nivel a detectar:"+Integer.parseInt(secureplace.Parametros.Audio_Nivel));
                    secureplace.SecurePlaceView.EtiquetaEstadoAudio.setText("Vigilando. Nivel:"+nivel+" de "+Parametros.Audio_Nivel);
                }
                
                if (ventanaConfiguracionAbierta) {
                    pintarBarraNivel(nivel);
                }
                //Si el nivel de audio sobrepasa el nivel configuado
                //entonces se guarda en un buffer

                if(nivel >= Integer.parseInt(secureplace.Parametros.Audio_Nivel)){
                    //Save data in output stream
                    // object.
                    byteArrayOutputStream.write(tempBuffer, 0, cnt);
                    ultimoFrameGuardado = true;
                    
                } else {
                    if (ultimoFrameGuardado) {
                        System.out.println(byteArrayOutputStream.size());
                        if (byteArrayOutputStream.size() > 0) {
                            secureplace.SecurePlaceApp.modo("Emergencia audio");
                            ultimoFrameGuardado = false;
                        }
                    }
                    
                }
            }//end while
            byteArrayOutputStream.close();
            secureplace.SecurePlaceView.EtiquetaEstadoAudio.setText("Inactivo");
        }catch (Exception e) {
          System.out.println(e);
          System.exit(0);
        }//end catch
    }//end run
}//end inner class CaptureThread

   static String guardarAudio() {
        AudioFormat audioFormat = getAudioFormat();
        System.out.println("Guardando audio"+secureplace.Parametros.fechaActual()+".wav");
        byte audio[] = byteArrayOutputStream.toByteArray();
        InputStream input = new ByteArrayInputStream(audio);
        AudioInputStream audioInputStream = new AudioInputStream(input, audioFormat, audio.length / audioFormat.getFrameSize());
        File archivoSalida = new File("audio"+secureplace.Parametros.fechaActual()+".wav");
        AudioFileFormat.Type targetType = AudioFileFormat.Type.WAVE;
        try {
            AudioSystem.write(
            audioInputStream,
            targetType,
            archivoSalida);
        } catch (IOException e) {
            e.getMessage();
        }
        byteArrayOutputStream.reset();
        return archivoSalida.toString();
    }

    private static AudioFormat getAudioFormat(){
    float sampleRate = 8000.0F;
    //8000,11025,16000,22050,44100
    int sampleSizeInBits = 16;
    //8,16
    int channels = 1;
    //1,2
    boolean signed = true;
    //true,false
    boolean bigEndian = false;
    //true,false
    return new AudioFormat(
                      sampleRate,
                      sampleSizeInBits,
                      channels,
                      signed,
                      bigEndian);
    }

    private static double[] frameToSignedDoubles(byte[] b) {
                int channels = 1;
		double[] d = new double[channels];
		for (int cc = 0; cc < channels; cc++) {
			d[cc] = (b[cc*2+1]*256 + (b[cc*2] & 0xFF))/32678.0;
		}

		return d;
    }

    private static void pintarBarraNivel(int nivel) {
        jProgressBar1.setValue(nivel);
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel2 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jProgressBar1 = new javax.swing.JProgressBar();
        jSlider1 = new javax.swing.JSlider();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(secureplace.SecurePlaceApp.class).getContext().getResourceMap(Audio.class);
        setTitle(resourceMap.getString("Form.title")); // NOI18N
        setName("Form"); // NOI18N
        setResizable(false);

        jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
        jLabel2.setName("jLabel2"); // NOI18N

        jLabel4.setText(resourceMap.getString("jLabel4.text")); // NOI18N
        jLabel4.setName("jLabel4"); // NOI18N

        jProgressBar1.setName("jProgressBar1"); // NOI18N

        jSlider1.setMinorTickSpacing(2);
        jSlider1.setPaintTicks(true);
        jSlider1.setSnapToTicks(true);
        jSlider1.setName("jSlider1"); // NOI18N

        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText(resourceMap.getString("jButton2.text")); // NOI18N
        jButton2.setName("jButton2"); // NOI18N
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jLabel3.setText(resourceMap.getString("jLabel3.text")); // NOI18N
        jLabel3.setName("jLabel3"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1))
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE)
                            .addComponent(jLabel3, 0, 0, Short.MAX_VALUE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)
                            .addComponent(jProgressBar1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)))
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel4)
                    .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 29, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton1)
                    .addComponent(jButton2))
                .addContainerGap())
        );

        jSlider1.setValue(Integer.parseInt(secureplace.Parametros.Audio_Nivel));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        ventanaConfiguracionAbierta = false;
        this.setVisible(false);
    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        
        secureplace.Parametros.Audio_Nivel = String.valueOf(jSlider1.getValue());
        secureplace.Parametros.guardarParametros();
    }//GEN-LAST:event_jButton1ActionPerformed

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                Audio dialog = new Audio(new javax.swing.JFrame(), true);
                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
                    @Override
                    public void windowClosing(java.awt.event.WindowEvent e) {
                        System.exit(0);
                    }
                });
                dialog.setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private static javax.swing.JProgressBar jProgressBar1;
    private javax.swing.JSlider jSlider1;
    // End of variables declaration//GEN-END:variables

}
